firmware_class: Return specific errors from file read
authorBen Hutchings <ben@decadent.org.uk>
Sat, 14 Dec 2013 17:14:39 +0000 (17:14 +0000)
committerBen Hutchings <ben@decadent.org.uk>
Thu, 17 Mar 2016 01:25:23 +0000 (01:25 +0000)
Currently several failure cases are not distinguished and are
incorrectly reported as -EINVAL or -ENOENT.

Change fw_file_size() to return an error code on failure and
adjust fw_read_file_contents() and fw_get_filesystem_firmware()

Change _request_firmware() to return the error code from
fw_get_filesystem_firmware() if CONFIG_FW_LOADER_USER_HELPER is not
enabled.  (If it is enabled and also fails, unfortunately we can't
tell why.)

Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Gbp-Pq: Topic bugfix/all
Gbp-Pq: Name firmware_class-return-specific-errors-from-file-read.patch

drivers/base/firmware_class.c

index 8524450e75bd15d8f97327af84662b4af32fc3a7..e65f6ffdc4af752192c4ba39b38a0c89653d9580 100644 (file)
@@ -298,7 +298,7 @@ static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
        int rc;
 
        if (!S_ISREG(file_inode(file)->i_mode))
-               return -EINVAL;
+               return -ENOTTY;
        size = i_size_read(file_inode(file));
        if (size <= 0)
                return -EINVAL;
@@ -307,7 +307,7 @@ static int fw_read_file_contents(struct file *file, struct firmware_buf *fw_buf)
                return -ENOMEM;
        rc = kernel_read(file, 0, buf, size);
        if (rc != size) {
-               if (rc > 0)
+               if (rc >= 0)
                        rc = -EIO;
                goto fail;
        }
@@ -348,8 +348,10 @@ static int fw_get_filesystem_firmware(struct device *device,
                }
 
                file = filp_open(path, O_RDONLY, 0);
-               if (IS_ERR(file))
+               if (IS_ERR(file)) {
+                       rc = PTR_ERR(file);
                        continue;
+               }
                rc = fw_read_file_contents(file, buf);
                fput(file);
                if (rc)
@@ -994,13 +996,6 @@ static void kill_requests_without_uevent(void)
 #endif
 
 #else /* CONFIG_FW_LOADER_USER_HELPER */
-static inline int
-fw_load_from_user_helper(struct firmware *firmware, const char *name,
-                        struct device *device, unsigned int opt_flags,
-                        long timeout)
-{
-       return -ENOENT;
-}
 
 /* No abort during direct loading */
 #define is_fw_load_aborted(buf) false
@@ -1152,6 +1147,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
        }
 
        ret = fw_get_filesystem_firmware(device, fw->priv);
+#ifdef CONFIG_FW_LOADER_USER_HELPER
        if (ret) {
                if (!(opt_flags & FW_OPT_NO_WARN))
                        dev_warn(device,
@@ -1163,6 +1159,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name,
                                                       opt_flags, timeout);
                }
        }
+#endif
 
        if (!ret)
                ret = assign_firmware_buf(fw, device, opt_flags);